#include "PrecompiledHeaders.h"
#include "StoryModeManager.h"
#include <cstdlib>

/*
 * Starts story mode on first level
 */
void StoryModeManager::enter(void)
{
    // Choose where to play bonuses
    currentLevelNum = 0;
    currentBonusIndex = 0;
    bonus = false;
    srand((unsigned)time(0));
    LevelVector::iterator it;
    std::vector<int>::iterator ri;
    bonuses.clear();
    std::vector<Level *>::iterator level_it, bonus_it;
    
    // Copy pointers to levels
    levelOrder.clear();
    for(it = resources->levels.begin(); it != resources->levels.end(); it++)
    {
        levelOrder.push_back(&(*it));
    }
    
    // Choose bonus numbers
    for(it = resources->bonusLevels.begin(); it != resources->bonusLevels.end(); it++)
    {
        int number = rand() % (int)(levelOrder.size() - 1) + 1;
        
        while(true) {
            for(ri = bonuses.begin(); ri!=bonuses.end(); ri++){
                if(*ri == number) break;
            }
            if(ri == bonuses.end()) break;
            number = rand() % (int)(levelOrder.size() - 1) + 1;
        }
        bonuses.push_back(number);
        printf("ADDED BONUS AFTER LEVEL %i\n",number);
    }
    
    // Insert bonuses
    int i;
    bool insertBonus;
    it = resources->bonusLevels.begin();
    for(i = (int)levelOrder.size() - 1; i > 0; i--)
    {
        insertBonus = false;
        for(ri = bonuses.begin(); ri!= bonuses.end(); ri++) {
            if(i == *ri) {
                insertBonus = true;
            }
        }
        if(insertBonus)
        {
            levelOrder.insert(levelOrder.begin()+i, &(*it));
            it++;
        }
    }
    
    // Initialise the first level
    next_level = levelOrder.begin();
    resources->current_level = *next_level;
    
    // initialise the current session
    session = new GameSession();
    sessions.push_back(session);
    
    // Display beginning story mode screen
    menu->setLayout((LayoutType)LOAD);
    pushGameState(findByName("in_game_menu"));
    currentState = psLOADING;
}

/*
 * If the player successfully completed the last level then 
 * go to next level, else return to menu
 */
void StoryModeManager::resume(void)
{
    updateStateFromMenu();
    switch(currentState)
    {
        case psPLAYING:
            updateStateFromSession(sessions[0]);
            
            // update bonus playing state
            if(bonus) {
                printf("ENDING BONUS RUN\n");
                sessions[0]->endBonusRun();
                currentState = psSUCCESSFUL;
                bonus = false;
            }
            
            resume();
            return;
    
        case psLOADING:
            // Set Sessions
            if(!bonus)
                sessions[0]->beginStoryModeLevel();
            else
                sessions[0]->beginBonusRun();
            suPlayState->setSession(sessions[0]);
            
            // Push game state 
            pushGameState(findByName("single_user_play"));
            currentState = psPLAYING;
            
            // Sort audio
            resources->audio->stopMenuBGM();
            resources->audio->playBGM();
            return;
            
        case psFINISHED:
            // Unload the level etc.
            resources->current_level->unload();
            clearSessions();
            menu->setState(lsNORMAL);
            popGameState();
            return;
            
        case psCREDITS:
            pushGameState(findByName("credits"));
            currentState = psFINISHED;
            return;
            
        case psSUCCESSFUL:
            // Set sessions and level
            sessions[0]->endStoryModeLevel(false);
            resources->current_level->setUnlocked(); // For bonus?
            currentLevelNum++;
            next_level++;
            
            // Display level complete screen or game complete
            menu->setLayout((LayoutType)SM_LEVEL_COMPLETE);
            if (next_level == levelOrder.end())
			{
                //menu->setLevelCompleteEndGame();
                menu->setLayout((LayoutType)SM_FINAL_LEVEL_COMPLETE);
                currentState = psCOMPLETE;
            }
            pushGameState(findByName("in_game_menu"));
            
            // See about playing a bonus
            if((*next_level)->isBonus()) {
                bonus = true;
            }
            
            // Set audio
            resources->audio->stopBGM();
            resources->audio->playMenuBGM();
            return;
        
        case psCOMPLETE:
            menu->setLayout((LayoutType)SM_COMPLETED);
            pushGameState(findByName("in_game_menu"));
            currentState = psCREDITS;
            return;
        
        case psNEXT_LEVEL:
            // Set sessions
            suPlayState->setSession(sessions[0]);
            
            // Load next level
            resources->current_level->unload();
            resources->current_level = *next_level;
            menu->setLayout((LayoutType)LOAD);
            pushGameState(findByName("in_game_menu"));
            currentState = psLOADING;
            return;            
        
        case psFAILED:
            // Set sessions
            sessions[0]->endStoryModeLevel(true);
            
            // Display game over screen
            menu->setLayout((LayoutType)SM_GAME_OVER);
            pushGameState(findByName("in_game_menu"));
            currentState = psFINISHED;
            
            // Set audio
            resources->audio->stopBGM();
            resources->audio->playMenuBGM();
            return;
            
        default:
            return;
    }
}
